package com.gy.nio;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ChannelTest {


    @Test
    public void test1() throws IOException {
        long startTIme = System.currentTimeMillis();

        //创建输入输出对象
        FileInputStream fis = new FileInputStream("mr/input.txt");
        FileOutputStream fos = new FileOutputStream("mr/input.txt.copy");

        //通过流对象或取通道对象channel
        FileChannel fisChannel = fis.getChannel();
        FileChannel fosChannel = fos.getChannel();

        //创建指定大小的缓冲区对象
        ByteBuffer buf = ByteBuffer.allocate(2014);

        //将通道中的数据写入缓冲区
        while (fisChannel.read(buf) != -1) {
            buf.flip();
            //将缓冲区数据写到输出通道
            fosChannel.write(buf);
            buf.clear();
        }

        //回收资源
        fisChannel.close();
        fosChannel.close();

        long endTime = System.currentTimeMillis();
        System.out.println("总耗时： " + (endTime - startTIme));
    }

    @Test
    public void test2() throws IOException {
        long startTIme = System.currentTimeMillis();

        //使用直接缓冲区完成文件的复制（基于内存映射文件）
        FileChannel inChannel = FileChannel.open(Paths.get("./mr/input.txt"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("./mr/input.txt.copy2"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW);

        //进行内存映射文件
        MappedByteBuffer inMapBuf = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
        MappedByteBuffer outMapBuf = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());

        //对缓冲区进行数据的读写操作
        byte[] dst = new byte[inMapBuf.limit()];
        inMapBuf.get(dst);
        outMapBuf.put(dst);

        //回收资源
        inChannel.close();
        outChannel.close();


        long endTime = System.currentTimeMillis();

        System.out.println("总耗时： " + (endTime - startTIme));
    }
}
